﻿using System;
using Pdelvo.Minecraft.Network;

namespace Pdelvo.Minecraft.Protocol.Packets
{
    /// <summary>
    /// 
    /// </summary>
    /// <remarks></remarks>
    public abstract class Packet
    {
        /// <summary>
        /// 
        /// </summary>
        public const int VERSION = 22;
        /// <summary>
        /// Gets or sets the code.
        /// </summary>
        /// <value>The code.</value>
        /// <remarks></remarks>
        public byte Code { get; protected set; }

        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="Packet"/> is cache.
        /// </summary>
        /// <value><c>true</c> if cache; otherwise, <c>false</c>.</value>
        /// <remarks></remarks>
        public bool Cache { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="Packet"/> is changed.
        /// </summary>
        /// <value><c>true</c> if changed; otherwise, <c>false</c>.</value>
        /// <remarks></remarks>
        public bool Changed { get; set; }

        /// <summary>
        /// Gets or sets the data.
        /// </summary>
        /// <value>The data.</value>
        /// <remarks></remarks>
        public byte[] Data { get; set; }

        /// <summary>
        /// Sends the specified stream.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <param name="version">The version.</param>
        /// <remarks></remarks>
        protected abstract void Send(BigEndianStream stream, int version);
        /// <summary>
        /// Receives the specified reader.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="version">The version.</param>
        /// <remarks></remarks>
        public abstract void Receive(BigEndianStream reader, int version);

        /// <summary>
        /// Sends the item.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <param name="version">The version.</param>
        /// <remarks></remarks>
        public void SendItem(BigEndianStream stream, int version)
        {
            if (Data != null && !Changed && stream.BufferEnabled)
            {
                stream.Write(Data, 0, Data.Length);
            }
            else
                Send(stream, version);
            stream.Flush();
        }
    }
}